package com.sqllog.admin.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.sqllog.admin.sql.domain.SqlLogInfo;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.mongodb.core.mapping.Document;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
import java.util.Objects;

/**
 * 通用工具
 *
 * @author chennengcheng
 * @date 2022-01-04 16:24
 * @remark
 */
public class CommonUtils {

    /**
     * 生成当月的表名
     *
     * @return
     */
    public static String generateTableNameByYearOfMonth(String dataBaseName, String tableName, String yearOfMonth){
       return dataBaseName.concat(StrUtil.DOT).concat(tableName).concat(StrUtil.DOT).concat(yearOfMonth);
    }

    /**
     * 获取sql记录
     *
     * @param id
     * @param sqlType
     * @return
     */
    public static SqlLogInfo getTableSqlListenerEntity(String id, String sqlType, String objType, Map<String, String> updateDataMap, String rowIdKey, String rowIdValue) {
        Date currentDate = new Date();
        SqlLogInfo sqlRecordEntity = new SqlLogInfo();
        sqlRecordEntity.setCreateDate(currentDate);
        sqlRecordEntity.setCreatTime(currentDate.getTime());
        updateDataMap.put(rowIdKey, rowIdValue);
        sqlRecordEntity.setDataMapOfJson(JSON.toJSONString(updateDataMap));
        sqlRecordEntity.setId(id);
        sqlRecordEntity.setType(sqlType);
        sqlRecordEntity.setRowIdKey(rowIdKey);
        sqlRecordEntity.setRowIdValue(rowIdValue);
        sqlRecordEntity.setObjType(objType);
        return sqlRecordEntity;
    }

    public static SqlLogInfo getTableSqlListenerEntity(String id, String sqlType, String objType, Map<String, String> updateDataMap) {
        return getTableSqlListenerEntity(
                id,
                sqlType,
                objType, updateDataMap, null, null);
    }


    @SuppressWarnings(value = "all")
    public static void updateDocumentCollectionName(Class clazz, String collectionName) {
        Document document = (Document) clazz.getAnnotation(Document.class);
        InvocationHandler invocationHandler = Proxy.getInvocationHandler(document);
        Field field = null;
        try {
            field = invocationHandler.getClass().getDeclaredField("memberValues");
            field.setAccessible(true);
            Map<String, Object> memberValues = (Map<String, Object>) field.get(invocationHandler);
            if (StringUtils.isBlank(collectionName)) {
                collectionName = document.collection();
            }

            memberValues.put("collection", collectionName);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

   public static class MemoryUnitInfo{
        private BigDecimal data;

        private String unit;

        public BigDecimal getData() {
            return data;
        }

        public void setData(BigDecimal data) {
            this.data = data;
        }

        public String getUnit() {
            return unit;
        }

        public void setUnit(String unit) {
            this.unit = unit;
        }
    }

    /**
     * 字节转kb/mb/gb
     * @param size
     * @return
     */
    public static MemoryUnitInfo getPrintSize(long size) {
        MemoryUnitInfo memoryUnitInfo = new MemoryUnitInfo();
        //如果字节数少于1024，则直接以B为单位，否则先除于1024，后3位因太少无意义
        if (size < 1024) {
            memoryUnitInfo.setData(new BigDecimal(size));
            memoryUnitInfo.setUnit("Byte");
            return memoryUnitInfo;
        } else {
            size = size / 1024;
        }
        //如果原字节数除于1024之后，少于1024，则可以直接以KB作为单位
        //因为还没有到达要使用另一个单位的时候
        //接下去以此类推
        if (size < 1024) {
            memoryUnitInfo.setData(new BigDecimal(size));
            memoryUnitInfo.setUnit("KB");
            return memoryUnitInfo;
        } else {
            size = size / 1024;
        }
        if (size < 1024) {
            //因为如果以MB为单位的话，要保留最后1位小数，
            //因此，把此数乘以100之后再取余
            size = size * 100;
            memoryUnitInfo.setData(new BigDecimal(size / 100 + "." + size % 100));
            memoryUnitInfo.setUnit("MB");
            return memoryUnitInfo;
        } else {
            //否则如果要以GB为单位的，先除于1024再作同样的处理
            size = size * 100 / 1024;
            memoryUnitInfo.setData(new BigDecimal(size / 100 + "." + size % 100));
            memoryUnitInfo.setUnit("GB");
            return memoryUnitInfo;
        }
    }

    /**
     * 获取当前月份表名
     *
     * @return
     */
    public static String getCurrentCollectionName(String collectionName) {
        return collectionName.concat(StrUtil.DOT).concat(DateUtil.format(new Date(), "yyyy-MM"));
    }

    /**
     * 获取当前月份表名
     *
     * @return
     */
    public static String getCurrentMonthName() {
        return DateUtil.format(new Date(), "yyyy-MM");
    }
}
